package com.baby.demo.utils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Jsons {

    private static final Logger LOGGER = LoggerFactory.getLogger(Jsons.class);

    private Jsons() {
    }

    public static Map<String, Object> json2map(String jsonStr) {
        Map<String, Object> map;
        if (jsonStr.startsWith("{")) {
            map = jsonObj2map(jsonStr);
        } else {
            map = jsonArr2map(jsonStr);
        }
        return map;
    }

    public static Map<String, Object> jsonArr2map(String jsonStr) {
        JSONArray jsonArr = JSONArray.fromObject(jsonStr);
        Map<String, Object> map = new HashMap<String, Object>();
        @SuppressWarnings("unchecked")
        Iterator<JSONObject> it = jsonArr.iterator();
        while (it.hasNext()) {
            JSONObject json2 = it.next();
            map.putAll(jsonObj2map(json2.toString()));
        }
        return map;
    }
    

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static Map<String, Object> jsonObj2map(String jsonStr) {
        Map<String, Object> map = new HashMap<String, Object>();
        // 最外层解析
        JSONObject json = JSONObject.fromObject(jsonStr);

        for (Object oentry : json.entrySet()) {
            Entry<String, Object> entry = (Entry<String, Object>) oentry;
            String key = entry.getKey();
            Object v = json.get(key);
            // 如果内层还是数组的话，继续解析
            if (v instanceof JSONArray) {
                List list = new ArrayList();
                Iterator<JSONObject> it = ((JSONArray) v).iterator();
                while (it.hasNext()) {
                    Object value = it.next();
                    if (value instanceof JSONObject) {
                        list.add(jsonObj2map(((JSONObject) value).toString()));
                    } else {
                        list.add(value);
                    }
                }
                map.put(key.toString(), list);
            } else if (v instanceof JSONObject) {
                String jsonObj = v.toString();
                map.put(key.toString(), jsonObj2map(jsonObj));
            } else {
                map.put(key.toString(), v);
            }
        }
        return map;
    }

    @SuppressWarnings("rawtypes")
    public static List json2list(String jsonStr) {
        JSONArray jsonArr = JSONArray.fromObject(jsonStr);
        List<Object> list = new ArrayList<Object>();
        @SuppressWarnings("unchecked")
        Iterator<JSONObject> it = jsonArr.iterator();
        while (it.hasNext()) {
            Object json2 = it.next();
            if (json2 instanceof String) {
                list.add(Strings.show(json2));
            } else {
                list.add(jsonObj2map(json2.toString()));
            }
        }
        return list;
    }

    public static String[] json2array(String jsonArray) {
        JSONArray jsonArr = JSONArray.fromObject(jsonArray);
        String[] list = new String[jsonArr.size()];
        @SuppressWarnings("unchecked")
        Iterator<JSONObject> it = jsonArr.iterator();
        int i = 0;
        while (it.hasNext()) {
            Object json2 = it.next();
            list[i] = Strings.show(json2);
            i++;
        }
        return list;
    }

    public static Map<String, Object> jsonFile2map(String path) {
        Map<String, Object> map = new HashMap<String, Object>();
        String json = Files.readFile(path);
        if ( Strings.isNotBlank(json)) {
            map = json2map(json);
        }
        return map;
    }

    @SuppressWarnings("unchecked")
    public static <T> List<T> jsonFile2list(String path) {
        List<T> list = null;
        String jsonStr = Files.readFile(path);
        if (Strings.isNotBlank(jsonStr)) {
            list = (List<T>) json2list(jsonStr);
        } else {
            list = new ArrayList<T>();
        }
        return list;
    }

    public static String map2json(Map<String, Object> map) {
        ObjectMapper mapper = new ObjectMapper();
        String jsonStr = Strings.EMPTY;
        try {
            return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map);
        } catch (JsonGenerationException e) {
            LOGGER.error(e.toString(), e);
        } catch (JsonMappingException e) {
            LOGGER.error(e.toString(), e);
        } catch (IOException e) {
            LOGGER.error(e.toString(), e);
        }
        return jsonStr;
    }

    public static String list2json(List<Map<String, Object>> list) {
        ObjectMapper mapper = new ObjectMapper();
        String jsonStr = Strings.EMPTY;
        try {
            return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(list);
        } catch (JsonGenerationException e) {
            LOGGER.error(e.toString(), e);
        } catch (JsonMappingException e) {
            LOGGER.error(e.toString(), e);
        } catch (IOException e) {
            LOGGER.error(e.toString(), e);
        }
        return jsonStr;
    }
}
